package demo

import (
	"fmt"
	"log"
	"math"
	"os"

	"gitee.com/general252/ebml-go"
	"gitee.com/general252/ebml-go/core"
	"gitee.com/general252/ebml-go/mkv"
	"gitee.com/general252/ebml-go/mkvcore"
	"gitee.com/general252/ebml-go/webm"
	"github.com/yapingcat/gomedia/go-codec"
	"github.com/yapingcat/gomedia/go-ogg"
)

func OpusDemo() {
	var filename = "outputOpus.ogg"
	var outFilename = "outOpus.mkv"

	w, err := os.OpenFile(outFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		log.Println(err)
		return
	} else {
		defer w.Close()
	}

	ws, err := webm.NewSimpleBlockWriter(w,
		[]*webm.TrackEntry{
			{
				Name:         "Audio",
				TrackNumber:  1,
				TrackUID:     12345,
				CodecID:      core.AudioCodecOPUS,
				TrackType:    core.TrackTypeAudio,
				CodecPrivate: nil,
				Audio: &webm.Audio{
					SamplingFrequency: float64(48000),
					Channels:          uint64(1),
				},
			},
		},
		mkvcore.WithSeekHead(true),
		mkvcore.WithCues(true),
		mkvcore.WithEBMLHeader(mkv.DefaultEBMLHeader),
		mkvcore.WithSegmentInfo(mkv.DefaultSegmentInfo),
		mkvcore.WithMaxKeyframeInterval(1, math.MaxInt16-5000),
	)

	if err != nil {
		log.Println(err)
		return
	} else {
		defer ws[0].Close()
	}

	audioStream := ws[0]

	oggDeuxer := ogg.NewDemuxer()
	oggDeuxer.OnFrame = func(streamId uint32, cid codec.CodecID, frame []byte, pts uint64, dts uint64, lost int) {
		oggDeuxer.GetAudioParam()
		log.Printf("streamId: %v codec: %v pts: %v frame: %v", streamId, cid, pts, len(frame))

		_, _ = audioStream.Write(true, int64(pts), frame)
	}
	oggDeuxer.OnPacket = func(streamId uint32, granule uint64, packet []byte, lost int) {
		//log.Printf("streamId: %v granule: %v packet: %v", streamId, granule, len(packet))
	}

	fp, _ := os.Open(filename)
	defer fp.Close()

	buf := make([]byte, 4096)
	for {
		if n, err := fp.Read(buf); err != nil {
			log.Println(err)
			break
		} else {
			if err = oggDeuxer.Input(buf[0:n]); err != nil {
				log.Println(err)
				break
			}
		}
	}

}

func OggReader() {
	// ffmpeg -i UA_444.mkv -vn -c:a libopus -b:a 64k outputOpus.ogg
	var filename = "outputOpus.ogg"
	if true {
		demuxer := ogg.NewDemuxer()

		demuxer.OnFrame = func(streamId uint32, cid codec.CodecID, frame []byte, pts uint64, dts uint64, lost int) {
			demuxer.GetAudioParam()
			log.Printf("streamId: %v codec: %v pts: %v frame: %v", streamId, cid, pts, len(frame))
		}
		demuxer.OnPacket = func(streamId uint32, granule uint64, packet []byte, lost int) {
			log.Printf("streamId: %v granule: %v packet: %v", streamId, granule, len(packet))
		}

		fp, _ := os.Open(filename)
		defer fp.Close()

		buf := make([]byte, 4096)
		for {
			n, err := fp.Read(buf)
			if err != nil {
				log.Println(err)
				break
			}

			err = demuxer.Input(buf[0:n])
			if err != nil {
				log.Println(err)
				break
			}
		}
	}

	if false {
		r, err := os.Open("outputOpus.webm")
		if err != nil {
			panic(err)
		}
		defer r.Close()

		var ret struct {
			Header  webm.EBMLHeader `ebml:"EBML"`
			Segment webm.Segment    `ebml:"Segment"`
		}
		if err := ebml.Unmarshal(r, &ret); err != nil {
			fmt.Printf("error: %v\n", err)
			return
		}

		var lenArray []int
		for _, cluster := range ret.Segment.Cluster {
			for _, block := range cluster.SimpleBlock {
				for _, data := range block.Data {
					_ = data
					lenArray = append(lenArray, len(data))
				}
			}
		}
		log.Println(lenArray, len(lenArray))
	}
}
